﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

using com.vs.DataAccess;
using com.vs.DataAccess.DO;
using com.vs.General;

namespace com.vs.Inventory.BL
{
    public class ItemManager
    {
        private static ItemManager _mgr = null;

        public static ItemManager GetInstance()
        {
            if (_mgr == null)
                _mgr = new ItemManager();
            return _mgr;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sess"></param>
        /// <param name="stCompany"></param>
        /// <param name="stItem"></param>
        /// <param name="iQty"></param>
        /// <returns>
        /// 返回值为各个单位上换算为基本单位的数量
        /// 比如：1PL=10CS=100EA
        /// 则：258个换算结果为
        /// PL: 200(个)
        /// CS: 50(个)
        /// EA: 8(个)
        /// </returns>
        public static Dictionary<string, int> BreakItemQtyIntoUMs(Session sess, 
            string stCompany, 
            string stItem,
            int iQty)
        {
            List<ItemUnitOfMeasureDO> lsUM = null;
            Dictionary<string, KeyValuePair<string, object>> dcCond = null;
            Dictionary<string, int> dcQtyInUM = null;
            int iLeftQty = iQty;

            try
            {
                dcCond = new Dictionary<string, KeyValuePair<string, object>>();
                dcQtyInUM = new Dictionary<string, int>();

                dcCond.Add("COMPANY", new KeyValuePair<string, object>("=", stCompany));
                dcCond.Add("ITEM", new KeyValuePair<string, object>("=", stItem));
                lsUM = ItemUnitOfMeasureDO.GetListByColumns(sess, DictionaryManager.ToList(dcCond), " ORDER BY SEQUENCE DESC");
                if (lsUM.Count < 1)
                    throw new Exception("货品单位未找到");

                foreach (ItemUnitOfMeasureDO umDO in lsUM)
                {
                    dcQtyInUM.Add(umDO.QUANTITY_UM, (iLeftQty / umDO.CONVERSION_QTY) * umDO.CONVERSION_QTY);
                    iLeftQty = iLeftQty % umDO.CONVERSION_QTY;
                }
                return dcQtyInUM;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return null;
            }
        }

        /// <summary>
        /// </summary>
        /// <param name="sess"></param>
        /// <param name="stCompany"></param>
        /// <param name="stItem"></param>
        /// <param name="stUM"></param>
        /// <returns>
        /// Dictionary<string, List<string>>：key值为数量单位；List为一组SQL语句。
        /// 理解为：对于单位1，优先尝试List(1)的库位范围；然后List(2)...
        /// </returns>
        public static Dictionary<string, List<string>> GetItemLocatingRule(Session sess,
            string stCompany,
            string stItem)
        {
            return null;
        }

        public string GetReplenishmentRule(Session sess, string stCompany, string stItem)
        {
            DataTable dt = null;
            DataHelper helper = null;

            try
            {
                helper = new DataHelper(sess);
                dt = helper.GetTable(CommandType.StoredProcedure, "ITM_RReplenishmentRule", new IDataParameter[]{
                    DataHelper.BuildParameter(sess, "@COMPANY", stCompany),
                    DataHelper.BuildParameter(sess, "@ITEM", stItem)});
                if (DataManager.IsEmpty(dt))
                    return null;
                else
                    return DataManager.GetString(dt.Rows[0], "REPLENISHMENT_RULE");
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return null;
            }
            finally
            {
                if (helper != null)
                    helper.Dispose();
            }
        }

        public static int GetConversionQty(Session sess, string stItem, string stComp, string stUM)
        {            
            DataHelper helper = null;
            DataTable dtModel = null;
            string stSQL = "ITM_RUOM";

            try
            {
                helper = new DataHelper(sess);
                dtModel = helper.GetTable(CommandType.StoredProcedure, stSQL, new IDataParameter[] { 
                            DataHelper.BuildParameter(sess, "@Item", stItem),
                            DataHelper.BuildParameter(sess, "@Company", stComp),
                            DataHelper.BuildParameter(sess, "@QuantityUM", stUM)
                        });
                if (DataManager.IsEmpty(dtModel))
                    return 0;
                return DataManager.GetInt(dtModel.Rows[0], "CONVERSION_QTY");
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return 0;
            }
            finally
            {
                if (helper != null)
                    helper.Dispose();
            }

        }

        public static int GetBaseQty(Session sess, string stItem, string stComp, int iQty, string stUM)
        {
            int iConvQty = 0;
            iConvQty = GetConversionQty(sess, stItem, stComp, stUM);

            return iConvQty * iQty;
        }

        public static string GetBaseUM(Session sess, string stItem, string stComp)
        {
            DataTable dt = null;
            Dictionary<string, KeyValuePair<string, object>> dcCond = null;

            try
            {
                dcCond = new Dictionary<string, KeyValuePair<string, object>>();
                dcCond.Add("ITEM", new KeyValuePair<string, object>("=", stItem));
                dcCond.Add("COMPANY", new KeyValuePair<string, object>("=", stComp));
                dcCond.Add("SEQUENCE", new KeyValuePair<string, object>("=", 1));
                dt = ItemUnitOfMeasureDO.GetTableByColumns(sess,DictionaryManager.ToList(dcCond), " ORDER BY SEQUENCE ASC");
                if (DataManager.IsEmpty(dt))
                    return MessageManager.MSG_ITM_001;//错误：未找到货品数量单位设定

                return DataManager.GetString(dt.Rows[0], "QUANTITY_UM");
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public ItemUnitOfMeasureDO GetParentUM(Session sess, string stItem, string stCompany, string stQtyUM)
        {
            List<ItemUnitOfMeasureDO> ltUM = null;
            Dictionary<string, KeyValuePair<string, object>> dcCond = null;
            ItemUnitOfMeasureDO umPrev = null;
            ItemUnitOfMeasureDO umParent = null;

            try
            {
                dcCond = new Dictionary<string, KeyValuePair<string, object>>();
                dcCond.Add("ITEM", new KeyValuePair<string, object>("=", stItem));
                dcCond.Add("COMPANY", new KeyValuePair<string, object>("=", stCompany));

                ltUM = ItemUnitOfMeasureDO.GetListByColumns(sess, DictionaryManager.ToList(dcCond), " ORDER BY SEQUENCE DESC");
                if (ltUM == null || ltUM.Count < 1)
                    return null;

                foreach (ItemUnitOfMeasureDO umDO in ltUM)
                {
                    if (StringManager.Equals(umDO.QUANTITY_UM, stQtyUM))
                    {
                        umParent = umPrev;
                        break;
                    }

                    umPrev = umDO;
                }
                return umParent;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return null;
            }
        }

        public ItemUnitOfMeasureDO GetChildUM(Session sess, string stItem, string stCompany, string stQtyUM)
        {
            List<ItemUnitOfMeasureDO> ltUM = null;
            Dictionary<string, KeyValuePair<string, object>> dcCond = null;
            ItemUnitOfMeasureDO umPrev = null;
            ItemUnitOfMeasureDO umChild = null;

            try
            {
                dcCond = new Dictionary<string, KeyValuePair<string, object>>();
                dcCond.Add("ITEM", new KeyValuePair<string, object>("=",stItem));
                dcCond.Add("COMPANY", new KeyValuePair<string, object>("=",stCompany));

                ltUM = ItemUnitOfMeasureDO.GetListByColumns(sess, DictionaryManager.ToList(dcCond), " ORDER BY SEQUENCE ASC");
                if (ltUM == null || ltUM.Count < 1)
                    return null;

                foreach (ItemUnitOfMeasureDO umDO in ltUM)
                {
                    if (StringManager.Equals(umDO.QUANTITY_UM, stQtyUM))
                    {
                        umChild = umPrev;
                        break;
                    }

                    umPrev = umDO;
                }
                return umChild;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return null;
            }
        }

        public static bool DoesItemTrackAttribute(Session sess, string stItem, string stComp)
        {
            DataTable dt = null;
            Dictionary<string, KeyValuePair<string, object>> dcCond = null;
            string stTrack = null;

            try
            {
                dcCond = new Dictionary<string, KeyValuePair<string, object>>();
                dcCond.Add("ITEM", new KeyValuePair<string, object>("=", stItem));
                dcCond.Add("COMPANY", new KeyValuePair<string, object>("=", stComp));
                dt = ItemDO.GetTableByColumns(sess, DictionaryManager.ToList(dcCond), null);
                if (DataManager.IsEmpty(dt))
                    throw new Exception("货品不存在");

                stTrack = DataManager.GetString(dt.Rows[0], "ATTRIBUTE_TRACK");
                return StringManager.Equals(stTrack, "Y") ? true : false;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public string NewItem(Session sess, ItemDO itemDO)
        {
            Dictionary<string, KeyValuePair<string, object>> dcCond = null;
            DataTable dt = null;

            try
            {
                //检查货品是否已存在
                dcCond = new Dictionary<string, KeyValuePair<string, object>>();
                dcCond.Add("ITEM", new KeyValuePair<string, object>("=", itemDO.ITEM));
                dcCond.Add("COMPANY", new KeyValuePair<string, object>("=", itemDO.COMPANY));
                dt = ItemDO.GetTableByColumns(sess, DictionaryManager.ToList(dcCond), null);

                if (!DataManager.IsEmpty(dt))
                    return MessageManager.MSG_ITM_002; //货品已存在

                return itemDO.Insert(sess);
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public string SaveItem(Session sess, ItemDO itemDO)
        {
            Dictionary<string, KeyValuePair<string, object>> dcCond = null;
            DataTable dt = null;

            try
            {
                //检查货品是否已存在
                dcCond = new Dictionary<string, KeyValuePair<string, object>>();
                dcCond.Add("ITEM", new KeyValuePair<string, object>("=", itemDO.ITEM));
                dcCond.Add("COMPANY", new KeyValuePair<string, object>("=", itemDO.COMPANY));
                dt = ItemDO.GetTableByColumns(sess, DictionaryManager.ToList(dcCond), null);

                if (DataManager.IsEmpty(dt))
                    return MessageManager.MSG_ITM_003; //货品不存在

                itemDO.Update(sess);
                return "" + itemDO.INTERNAL_ITEM_NUM;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public string SaveItemUOM(Session sess, ItemUnitOfMeasureDO itemUOMDO)
        {
            Dictionary<string, KeyValuePair<string, object>> dcCond = null;
            DataTable dt = null;

            try
            {
                //检查货品是否已存在
                dcCond = new Dictionary<string, KeyValuePair<string, object>>();
                dcCond.Add("ITEM", new KeyValuePair<string, object>("=", itemUOMDO.ITEM));
                dcCond.Add("COMPANY", new KeyValuePair<string, object>("=", itemUOMDO.COMPANY));
                dcCond.Add("QUANTITY_UM", new KeyValuePair<string, object>("=", itemUOMDO.QUANTITY_UM));
                dt = ItemUnitOfMeasureDO.GetTableByColumns(sess, DictionaryManager.ToList(dcCond), " ORDER BY SEQUENCE ASC");

                if (DataManager.IsEmpty(dt))
                {
                    return "" + itemUOMDO.Insert(sess);
                }
                else
                {
                    itemUOMDO.Update(sess);
                    return "" + itemUOMDO.INTERNAL_ITEM_UM;
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static List<ItemUnitOfMeasureDO> GetItemUOMIntoList(Session sess, string stItem, string stCompany, bool bInASCOrder)
        {       
            List<ItemUnitOfMeasureDO> lsUM = null;
            Dictionary<string, KeyValuePair<string, object>> dcCond = null;

            try
            {
                dcCond = new Dictionary<string, KeyValuePair<string, object>>();

                dcCond.Add("COMPANY", new KeyValuePair<string, object>("=", stCompany));
                dcCond.Add("ITEM", new KeyValuePair<string, object>("=", stItem));
                lsUM = ItemUnitOfMeasureDO.GetListByColumns(sess, DictionaryManager.ToList(dcCond), " ORDER BY SEQUENCE " + (bInASCOrder ? "ASC" : "DESC"));
                if (lsUM.Count < 1)
                    throw new Exception("货品单位未找到");
                return lsUM;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return null;
            }
        }

        public static DataTable GetItemUOMIntoTable(Session sess, string stItem, string stCompany, bool bInASCOrder)
        {
            Dictionary<string, KeyValuePair<string, object>> dcCond = null;

            try
            {
                dcCond = new Dictionary<string, KeyValuePair<string, object>>();

                dcCond.Add("COMPANY", new KeyValuePair<string, object>("=", stCompany));
                dcCond.Add("ITEM", new KeyValuePair<string, object>("=", stItem));
                return ItemUnitOfMeasureDO.GetTableByColumns(sess, DictionaryManager.ToList(dcCond), " ORDER BY SEQUENCE " + (bInASCOrder ? "ASC" : "DESC"));
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return null;
            }
        }

    }
}